﻿/*
 * stdlib.h
 *
 */
#ifndef __GDK_STDLIB_H__
#define __GDK_STDLIB_H__


#include <gdk/core/Types.h>
#include <cstdarg>
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <fcntl.h>

#ifdef _WIN32
#   include <malloc.h>
#	include <tchar.h>
#	include <mbstring.h>
#	include <io.h>
#else
#	include <sys/stat.h>
#	include <unistd.h>
#endif

#if !defined(_WIN32)
#	if defined(__ANDROID__) || defined(__IOS__)
#		define _stat64 stat
#	else
#		define _stat64 stat64
#	endif
#endif

#if defined(_WIN32)
#	define __sys_sleep(milliseconds)  ::Sleep(milliseconds)
#else
#	define __sys_sleep(milliseconds)  ::usleep(milliseconds * 1000);
#endif

#if defined(__ANDROID__)
GDK_CORE_EXPORT int wcscasecmp(const wchar_t *cs, const wchar_t *ct);
#endif


namespace gdk
{


#if defined(_WIN32)

	__INLINE__ static int wstat(const wchar_t * fileName, struct _stat64 * info)
	{
		return ::_wstat64(fileName, info);
	}

#if !defined(_UNICODE)

	#define __printf   ::printf
	#define __sprintf  ::sprintf
	#define __vsprintf ::vsprintf
	#define __sscanf   ::sscanf

	#define __fopen    ::fopen
	#define __fputs    ::fputs
	#define __fprintf  ::fprintf
	#define __remove   ::remove
	#define __open     ::_open
	#define __fdopen   ::fdopen
	#define __stat     ::_stat64
	#define __fseek    ::_fseeki64
	#define __ftell    ::_ftelli64

	#define __strcpy   ::strcpy
	#define __strcat   ::strcat
	#define __strcmp   ::strcmp
	#define __stricmp  ::stricmp
	#define __strrchr  ::strrchr
	#define __strupr   ::strupr
	#define __strstr   ::strstr
	#define __strchr   ::strchr
	#define __strlen   ::strlen
	#define __strncpy  ::strncpy
	#define __strcspn  ::strcspn
	#define __strncmp  ::strncmp
	#define __strnicmp ::strnicmp
	#define __strpbrk  ::strpbrk

	#define __atoi     ::atoi
	#define __itoa     ::itoa
	#define __atoi64   ::_atoi64
	#define __i64toa   ::_i64toa
	#define __atof     ::atof
	#define __strtod   ::strtod

	#define __strftime ::strftime

#else //_UNICODE

	#define __printf   ::wprintf
	#define __sprintf  ::swprintf
	#define __vsprintf ::vswprintf
	#define __sscanf   ::swscanf

	#define __fopen    ::_wfopen
	#define __fputs    ::fputws
	#define __fprintf  ::fwprintf
	#define __remove   ::_wremove
	#define __open     ::_wopen
	#define __fdopen   ::_wfdopen
	#define __stat     gdk::wstat
	#define __fseek    ::_fseeki64
	#define __ftell    ::_ftelli64

	#define __strcpy   ::wcscpy
	#define __strcat   ::wcscat
	#define __strcmp   ::wcscmp
	#define __stricmp  ::wcsicmp
	#define __strrchr  ::wcsrchr
	#define __strupr   ::_wcsupr
	#define __strstr   ::wcsstr
	#define __strchr   ::wcschr
	#define __strlen   ::wcslen
	#define __strncpy  ::wcsncpy
	#define __strcspn  ::wcscspn
	#define __strncmp  ::wcsncmp
	#define __strnicmp ::wcsnicmp
	#define __strpbrk  ::wcspbrk

	#define __atoi     ::_wtoi
	#define __atoi64   ::_wtoi64
	#define __atof     ::_wtof
	#define __itoa     ::_itow
	#define __i64toa   ::_i64tow
	#define __strtod   ::wcstod

	#define __strftime ::wcsftime

#endif //_UNICODE


#else //_WIN32


GDK_CORE_EXPORT FILE* wfopen(const wchar_t * fileName, const wchar_t * mode);
GDK_CORE_EXPORT int   wremove(const wchar_t * fileName);
GDK_CORE_EXPORT int   wopen(const wchar_t * fileName, int flags, int pmode);
GDK_CORE_EXPORT FILE* wfdopen(int fd, const wchar_t * mode);
GDK_CORE_EXPORT int   wstat(const wchar_t * fileName, struct _stat64 * info);

GDK_CORE_EXPORT int swprintf(wchar_t *str, const wchar_t *fmt, ...) __WPRINTF_FORMAT__(2, 3);
GDK_CORE_EXPORT double wtod(const wchar_t *ptr, wchar_t **endptr);
__INLINE__ int32_t  wtoi(const wchar_t *s) { wchar_t *e; return (int32_t)::wcstol(s, &e, 10); }
__INLINE__ wchar_t* itow(int32_t n, wchar_t *s,int) { swprintf(s, L"%d", n); return s; }
#if defined(__x86_64__)
__INLINE__ wchar_t* i64tow(int64_t n, wchar_t *s,int) { swprintf(s, L"%ld", n); return s; }
__INLINE__ char*    i64toa(int64_t n, char *s,int) { sprintf(s, "%ld", n); return s; }
#else
__INLINE__ wchar_t* i64tow(int64_t n, wchar_t *s,int) { swprintf(s, L"%lld", n); return s; }
__INLINE__ char*    i64toa(int64_t n, char *s,int) { sprintf(s, "%lld", n); return s; }
#endif

#if defined(__ANDROID__)
GDK_CORE_EXPORT int64_t wtoi64(const wchar_t *s);
GDK_CORE_EXPORT float   wtof(const wchar_t *s);
#else
__INLINE__ int64_t wtoi64(const wchar_t *s) { wchar_t *e; return ::wcstoll(s, &e, 10); }
__INLINE__ float   wtof(const wchar_t *s) { wchar_t *e; return ::wcstof(s, &e); }
#endif


#if !defined(_UNICODE)

	#define __printf   ::printf
	#define __sprintf  ::sprintf
	#define __vsprintf ::vsprintf
	#define __sscanf   ::sscanf

	#define __fopen    ::fopen
	#define __fputs    ::fputs
	#define __fprintf  ::fprintf
	#define __remove   ::remove
	#define __open     ::open
	#define __fdopen   ::fdopen
#if defined(__IOS__)
	#define __stat     ::stat
#else
	#define __stat     ::stat64
#endif
#if defined(__ANDROID__) || defined(__IOS__)
	#define __fseek    ::fseek
	#define __ftell    ::ftell
#else
	#define __fseek    ::fseeko64
	#define __ftell    ::ftello64
#endif

	#define __strcpy   ::strcpy
	#define __strcat   ::strcat
	#define __strcmp   ::strcmp
	#define __stricmp  ::strcasecmp
	#define __strrchr  ::strrchr
	#define __strupr   ::strupr
	#define __strstr   ::strstr
	#define __strchr   ::strchr
	#define __strlen   ::strlen
	#define __strncpy  ::strncpy
	#define __strcspn  ::strcspn
	#define __strncmp  ::strncmp
	#define __strnicmp ::strncasecmp
	#define __strpbrk  ::strpbrk

	#define __atoi     ::atoi
	#define __itoa     ::itoa
	#define __atoi64   ::atoll
	#define __i64toa   gdk::i64toa
	#define __atof     ::atof
	#define __strtod   ::strtod

	#define __strftime ::strftime

#else //_UNICODE

	#define __printf   ::wprintf
	#define __sprintf  gdk::swprintf
	#define __vsprintf ::vswprintf
	#define __sscanf   ::swscanf

	#define __fopen    gdk::wfopen
	#define __fputs    ::fputws
	#define __remove   gdk::wremove
	#define __open     gdk::wopen
	#define __fdopen   gdk::wfdopen
	#define __stat     gdk::wstat
#if defined(__ANDROID__) || defined(__IOS__)
	#define __fseek    ::fseek
	#define __ftell    ::ftell
#else
	#define __fseek    ::fseeko64
	#define __ftell    ::ftello64
#endif

	#define __strcpy   ::wcscpy
	#define __strcat   ::wcscat
	#define __strcmp   ::wcscmp
	#define __stricmp  ::wcscasecmp
	#define __strrchr  ::wcsrchr
	#define __strupr   ::_wcsupr
	#define __strstr   ::wcsstr
	#define __strchr   ::wcschr
	#define __strlen   ::wcslen
	#define __strncpy  ::wcsncpy
	#define __strcspn  ::wcscspn
	#define __strncmp  ::wcsncmp
	#define __strnicmp ::wcsncasecmp
	#define __strpbrk  ::wcspbrk

	#define __atoi     gdk::wtoi
	#define __itoa     gdk::itow
	#define __atoi64   gdk::wtoi64
	#define __i64toa   gdk::i64tow
	#define __atof     gdk::wtof
	#define __strtod   gdk::wtod

	#define __strftime ::wcsftime

#endif //_UNICODE


#endif //_WIN32





}//namespace gdk




#endif /*__GDK_ALLOCATOR_H__*/
